﻿using System;
using System.Windows.Input;
using System.Xml.Serialization;
using System.Threading.Tasks;
using Microsoft.Practices.Prism.Commands;

namespace HobSoft.SoccerBet2014.Client.ViewModels
{
    using Common;
    using Domain.ClientService;
    using dmr = Domain.Models.BfRaw;
    [Serializable]
    [XmlRoot("order")]
    public class BfOrder : CommandViewModel
    {

        public event EventHandler<string> OnCancelSucceed;
        [XmlIgnore]
        public ICommand CancelOrderCommand { get; protected set; }

        public BfOrder(IBfRequestService _bfRequestService)
        {
            CancelOrderCommand = new DelegateCommand(CancelOrder);
            bfRequestService = _bfRequestService;
        }

        private IBfRequestService bfRequestService;
        protected void CancelOrder()
        {
            if (bfRequestService == null) return;
            bfRequestService.CancelOrder(MarketID, new dmr.CancelInstruction { BetId = BetID }, null).ContinueWith(t =>
            {
                if (t.Exception != null)
                {
                    PublicLog.ErrorFormat("取消订单发生错误：{0}", t.Exception.InnerException.Message);
                }
                if (t.IsCompleted)
                {
                    if (t.Result != null)
                    {
                        if (t.Result.Status == dmr.ExecutionReportStatus.SUCCESS)
                        {
                            string betId = string.Empty;
                            if (t.Result.InstructionReports.Count > 0)
                                betId = t.Result.InstructionReports[0].Instruction.BetId;
                            if (t.Result.InstructionReports.Count > 0)
                                PublicLog.InfoFormat("订单{0}已经取消", betId);
                            else
                                PublicLog.Info("订单已经取消");
                            RaiseCancelCancelSucceed(betId);
                        }
                        else
                        {
                            RaiseCancelOrderError(t.Result);
                        }
                    }
                }
            });
        }

        protected void RaiseCancelOrderError(dmr.CancelExecutionReport cancelReport)
        {
            string betId = string.Empty;
            if (cancelReport.InstructionReports.Count > 0)
                betId = cancelReport.InstructionReports[0].Instruction.BetId;
            switch (cancelReport.Status)
            {
                case dmr.ExecutionReportStatus.FAILURE:
                    var failed = string.Format("取消订单{0}失败，错误代码{1}", betId, cancelReport.ErrorCode);
                    RaiseMessage("取消订单", failed, 10);
                    PublicLog.InfoFormat("取消订单{0}失败，错误代码{1}", betId, cancelReport.ErrorCode);
                    break;
                case dmr.ExecutionReportStatus.PROCESSED_WITH_ERRORS:
                    var error = string.Format("取消订单{0}错误，错误代码{1}", betId, cancelReport.ErrorCode);
                    RaiseMessage("取消订单", error, 10);
                    PublicLog.InfoFormat("取消订单{0}错误，错误代码{1}", betId, cancelReport.ErrorCode);
                    break;
                case dmr.ExecutionReportStatus.TIMEOUT:
                    var timeout = string.Format("取消订单{0}超时，错误代码{1}", betId, cancelReport.ErrorCode);
                    RaiseMessage("取消订单", timeout, 10);
                    PublicLog.InfoFormat("取消订单超时，错误代码{1}", betId, cancelReport.ErrorCode);
                    break;
                default:
                    break;
            }
        }

        protected void RaiseCancelCancelSucceed(string betId)
        {
            if (OnCancelSucceed != null)
                OnCancelSucceed(this, betId);
        }

        #region model property
        private string _betId;
        [XmlAttribute("bet-id")]
        public string BetID
        {
            get { return _betId; }
            set { PropertyValueChange(ref _betId, value, "BetID"); }
        }


        private int _selectionID;
        [XmlAttribute("id")]
        public int SelectionID
        {
            get { return _selectionID; }
            set { PropertyValueChange(ref _selectionID, value, "SelectionID"); }
        }

        private string _marketID;
        [XmlAttribute("market-id")]
        public string MarketID
        {
            get { return _marketID; }
            set { PropertyValueChange(ref _marketID, value, "MarketID"); }
        }

        private string _homeTeam;
        [XmlAttribute("home-team")]
        public string HomeTeam
        {
            get { return _homeTeam; }
            set { PropertyValueChange(ref _homeTeam, value, "HomeTeam"); }
        }

        private string _awayTeam;
        [XmlAttribute("away-team")]
        public string AwayTeam
        {
            get { return _awayTeam; }
            set { PropertyValueChange(ref _awayTeam, value, "AwayTeam"); }
        }

        private string _runnerName;
        [XmlAttribute("name")]
        public string RunnerName
        {
            get { return _runnerName; }
            set { PropertyValueChange(ref _runnerName, value, "RunnerName"); }
        }

        private dmr.Side _side;
        [XmlAttribute("buy")]
        public dmr.Side Side
        {
            get { return _side; }
            set { PropertyValueChange(ref _side, value, "Side"); }
        }

        private decimal _price;
        [XmlAttribute("price")]
        public decimal Price
        {
            get { return _price; }
            set { PropertyValueChange(ref _price, value, "Price"); }
        }

        private decimal _amount;
        [XmlAttribute("amount")]
        public decimal Amount
        {
            get { return _amount; }
            set { PropertyValueChange(ref _amount, value, "Amount"); }
        }

        private decimal _orderAmount;
        [XmlAttribute("order-amount")]
        public decimal OrderAmount
        {
            get { return _orderAmount; }
            set { PropertyValueChange(ref _orderAmount, value, "OrderAmount"); }
        }

        private decimal _turnover;
        [XmlAttribute("turnover")]
        public decimal OrderTurnover
        {
            get { return _turnover; }
            set { PropertyValueChange(ref _turnover, value, "OrderTurnover"); }
        }

        private dmr.OrderStatus _oderState;
        [XmlAttribute("oder-state")]
        public dmr.OrderStatus OrderState
        {
            get { return _oderState; }
            set { PropertyValueChange(ref _oderState, value, "OrderState"); }
        }

        private DateTime _submitTime;
        [XmlAttribute("submit-time")]
        public DateTime SubmitTime
        {
            get { return _submitTime; }
            set { PropertyValueChange(ref _submitTime, value, "SubmitTime"); }
        }
        #endregion

        private long _version;
        [XmlIgnore]
        public long Version
        {
            get { return _version; }
            set { _version = value; }
        }

    }

}
